package com.million.project.service.serviceimpl;



import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.million.project.mapper.AuditLogsMapper;
import com.million.project.mapper.RoadApplyLogsMapper;
import com.million.project.mapper.RoadNodesMapper;
import com.million.project.mapper.UsersMapper;
import com.million.project.pojo.*;
import com.million.project.service.IRoadApplyLogsService;
import com.million.project.utils.DateUtil;
import com.million.project.utils.DragonResult;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 小龙
 * @since 2022-10-26
 */
@Service
public class RoadApplyLogsServiceImpl extends ServiceImpl<RoadApplyLogsMapper, RoadApplyLogs> implements IRoadApplyLogsService {

    @Autowired
    RoadApplyLogsMapper applyLogsDao;

    @Autowired
    AuditLogsMapper auditLogsDao;

    @Autowired
    UsersMapper usersDao;

    @Autowired
    RoadNodesMapper roadNodesMapper;

    /**
     * 显示 正在审核（audit_status=0）的审核信息 申报时间、起始地、终点地。
     *
     * @return
     */
    @Override
    public List<RoadApplyLogs> getAllApplyLogsPage(String username) {

        List<RoadApplyLogs> allApplyLogs = applyLogsDao.getAllApplyLogs(username);

        // 2.再接着根据收费站id，查找收费站结点的名字
        for (int i = 0; i < allApplyLogs.size(); i++) {

            RoadApplyLogs roadApplyLogs = allApplyLogs.get(i);
            if (roadApplyLogs.getWhetherUseAdvice() == 1 || roadApplyLogs.getWhetherUseAdvice() == 2) {
                if(roadApplyLogs.getWhetherUseAdvice() == 1) {
                    // 2.1 如果是使用高德推荐路线或者AI推荐的，那就直接利用结点id查出名字
                    String begin = roadNodesMapper.selectById(roadApplyLogs.getRoadBegin());
                    System.out.println(begin);
                    roadApplyLogs.setRoadBeginName(begin);
                    String end = roadNodesMapper.selectById(roadApplyLogs.getRoadEnd());
                    System.out.println(end);
                    roadApplyLogs.setRoadEndName(end);
                }else{
                    // 如果是智能AI，那就将起点、终点提取出来
                    String suggestRoad = roadApplyLogs.getSuggestRoad();
                    String[] split = suggestRoad.split("---");
                    for (int j = 0; j < split.length; j++) {
                        System.out.println(split[j]);
                    }
                    roadApplyLogs.setRoadBeginName(split[0]);
                    roadApplyLogs.setRoadEndName(split[split.length - 1]);
                }
            } else {
                // 2.2 没有使用推荐路线，而是用户输入的路线
                //     那么就要从用户的输入中提取
                String initRoad = roadApplyLogs.getInitRoad();

                System.out.println(initRoad);
                String[] split = initRoad.split("---");
                for (int j = 0; j < split.length; j++) {
                    System.out.println(split[j]);
                }
                roadApplyLogs.setRoadBeginName(split[0]);
                roadApplyLogs.setRoadEndName(split[split.length - 1]);
            }
        }
        System.out.println("审核中的申报返回的信息为："+allApplyLogs.toString());
        return allApplyLogs;
    }

    /**
     * 返回某条申报信息的详细信息
     *
     * @param roadApplyLogs 传入的申报信息id
     * @param username
     * @return
     */
    @Override
    public DragonResult getDeepApply(RoadApplyLogs roadApplyLogs, String username) {

        RoadApplyLogs applyLogs = (RoadApplyLogs) query().eq("road_apply_logs_id",

                roadApplyLogs.getRoadApplyLogsId()).eq("username", username).one();

        if (applyLogs != null) {
            return DragonResult.ok(applyLogs);
        } else {
            return DragonResult.fail("该申报信息不存在！");
        }
    }

    /**
     * 撤回某条申报记录、从路线申报表中删除即可。
     *
     * @param roadApplyLogs
     * @param username
     * @return
     */
    @Override
    public DragonResult retractApply(RoadApplyLogs roadApplyLogs, String username) {

        int number = applyLogsDao.updateAuditStatus(roadApplyLogs.getRoadApplyLogsId(), username);

        if (number > 0) {
            return DragonResult.ok("撤回成功！");
        } else {
            return DragonResult.fail("撤回失败");
        }
    }

    /**
     * 查询出用户所有历史申报
     *
     * @param username
     * @return
     */
    @Override
    public List<RoadApplyLogs> getHistoryPage(String username) {

        // 1、首先分页查询出来该用户的所有历史申报
        List<RoadApplyLogs> allApplyLogs = applyLogsDao.selectHistoryPage(username);
        List<RoadApplyLogs> resultApplyLogs=new ArrayList<>();

        for (RoadApplyLogs s:allApplyLogs) {
            System.out.println(s);
        }
        // 2.再接着根据收费站id，查找收费站结点的名字
        for (int i = 0; i < allApplyLogs.size(); i++) {
            RoadApplyLogs roadApplyLogs = allApplyLogs.get(i);
            if (roadApplyLogs.getWhetherUseAdvice() == 1) {
                // 2.1 如果是使用推荐路线的，那就直接利用结点id查出名字
                String begin = roadNodesMapper.selectById(roadApplyLogs.getRoadBegin());
                System.out.println(begin);
                roadApplyLogs.setRoadBeginName(begin);
                String end = roadNodesMapper.selectById(roadApplyLogs.getRoadEnd());
                System.out.println(end);
                roadApplyLogs.setRoadEndName(end);
            } else if(roadApplyLogs.getWhetherUseAdvice() == 0){
                // 2.2 没有使用推荐路线，而是用户输入的路线
                //     那么就要从用户的输入中提取
                // 其实都可以根据结点id从结点表找出来。用户输入的节点也存入了节点表。
                String initRoad = roadApplyLogs.getInitRoad();

                System.out.println(initRoad);
                String[] split = initRoad.split("---");
                for (int j = 0; j < split.length; j++) {
                    System.out.println(split[j]);
                }
                roadApplyLogs.setRoadBeginName(split[0]);
                roadApplyLogs.setRoadEndName(split[split.length - 1]);
            }
        }
            // 3.再将每一条申报的审核结果根据申报记录的id从审核记录表里查询出来：
            for (int i = 0; i < allApplyLogs.size(); i++) {
                RoadApplyLogs applylogs = allApplyLogs.get(i);
                // 根据申报路线信息的id查找出对应的审核信息
                AuditLogs auditLogs = auditLogsDao.selectByApplyId(applylogs.getRoadApplyLogsId());
                // 审核表里没有的说明正在审核，不是历史审核,删掉
                System.out.println(" for的每一次:");
                System.out.println(auditLogs);
                if (auditLogs == null) {
                    // 为空就不作处理
                    continue;
                } else  { //存在，设置
                    System.out.println("输出完善前审核记录———————————————————————————————");
                    System.out.println(auditLogs);
                    applylogs.setPassOrNotPassReason(auditLogs.getWhetherPassReason());
                    if (auditLogs.getWhetherPass()) {
                        applylogs.setIsPass("通过");
                    } else {
                        applylogs.setIsPass("未通过");
                    }
                    System.out.println("输出完善后审核记录———————————————————————————————");
                    System.out.println(auditLogs);
                    resultApplyLogs.add(applylogs);
                }
            }
        System.out.println("输出返回信息");
        System.out.println(allApplyLogs);
        // 3.将封装好的信息返回
        return resultApplyLogs;
    }

    /**
     * 根据id删除用户历史申报记录
     *
     * @param roadApplyLogs
     * @return
     */
    @Override
    public DragonResult deleteHistoryLog(RoadApplyLogs roadApplyLogs) {
        int number = applyLogsDao.updateHistoryLogById(roadApplyLogs.getRoadApplyLogsId());

        if (number > 0) {
            return DragonResult.ok();
        } else {
            return DragonResult.fail("删除失败");
        }
    }

    /**
     * 查看审核通过的历史记录
     *
     * @param username
     * @return
     */
    @Override
    public List<RoadApplyLogs> getPassPage(String username) throws IOException {

        List<RoadApplyLogs> roadApplyLogs = this.getHistoryPage(username);

        for (int i = 0; i < roadApplyLogs.size(); i++) {
            roadApplyLogs.get(i).setPassOrNotPassReason("申请合理，请求通过");
            if ("未通过".equals(roadApplyLogs.get(i).getIsPass())) {
                roadApplyLogs.remove(i);
            }
        }
        return roadApplyLogs;
    }

    /**
     * 获得所有未通过的历史申报
     *
     * @param username
     * @return
     * @throws IOException
     */
    @Override
    public List<RoadApplyLogs> getNotPassPage(String username) throws IOException {
        List<RoadApplyLogs> roadApplyLogs = this.getHistoryPage(username);

        List<RoadApplyLogs> nowRoadApply = new ArrayList<>();
        System.out.println(roadApplyLogs);
        for (int i = 0; i < roadApplyLogs.size(); i++) {
            if ("未通过".equals(roadApplyLogs.get(i).getIsPass())) {
                System.out.println("----------------");
                System.out.println(roadApplyLogs.get(i));
                System.out.println("------------------");
                nowRoadApply.add(roadApplyLogs.get(i));
            }
        }
        System.out.println(roadApplyLogs);
        return nowRoadApply;
    }

    /**
     * 返回最近6个月的路线申请统计信息
     *
     * @return
     */
    @Override
    public List <Integer> getNumByDate() {
        List <Integer> list = new ArrayList<>();
        String back = DateUtil.date2Str(Calendar.getInstance().getTime(), "yyyy-MM-dd");
        String front = DateUtil.getBeforeMonthTime(0);
        list.add(applyLogsDao.selectNumBetweenDate(front, back));
        back = front;
        front = DateUtil.getBeforeMonthTime(1);
        list.add(applyLogsDao.selectNumBetweenDate(front, back));
        back = front;
        front = DateUtil.getBeforeMonthTime(2);
        list.add(applyLogsDao.selectNumBetweenDate(front, back));
        back = front;
        front = DateUtil.getBeforeMonthTime(3);
        list.add(applyLogsDao.selectNumBetweenDate(front, back));
        back = front;
        front = DateUtil.getBeforeMonthTime(4);
        list.add(applyLogsDao.selectNumBetweenDate(front, back));
        back = front;
        front = DateUtil.getBeforeMonthTime(5);
        list.add(applyLogsDao.selectNumBetweenDate(front, back));
        Collections.reverse(list);//逆序
        return list;
    }


    /**
     * 提交司机的路线申请
     *
     * @param roadApplyLogs
     * @param nodeLngLat
     * @return
     */
    @Override
    public DragonResult submitRoadApply(RoadApplyLogs roadApplyLogs, NodeLngLat nodeLngLat) {

        // 1.首先将初始字段默认
        // 初始化未审核
        roadApplyLogs.setAuditStatus("0");

        // 初始化未删除
        roadApplyLogs.setDeleted(0);
        System.out.println(roadApplyLogs.getDeleted());

        // 2.判断是否使用推荐路线
        // 2.1 如果没有使用最新的智能推荐路线，那就按照老规矩处理
        if(roadApplyLogs.getWhetherUseAdvice() != 2){
            if (roadApplyLogs.getWhetherUseAdvice() == 0) {
                // 2.1 未使用,如果未使用推荐路线，那就不需要经纬度，因此不需要将结点存入
                roadApplyLogs.setInitRoad(roadApplyLogs.getSuggestRoad());
                roadApplyLogs.setSuggestRoad(null);
            } else if(roadApplyLogs.getWhetherUseAdvice() == 1){
                // 2.2 使用高德推荐的路线，那就提取出起点和终点的名字，并进行判断
                String[] split = roadApplyLogs.getSuggestRoad().split("---");
                for (int j = 0; j < split.length; j++) {
                    System.out.println(split[j]);
                }
                roadApplyLogs.setRoadBeginName(split[0]); // 赋予起点名
                roadApplyLogs.setRoadEndName(split[split.length - 1]);// 赋予终点名

                // 3.从节点表中查找整个结点，先判断是否已经存在，不存在就插入
                Integer byBeginName = roadNodesMapper.selectIdByName(roadApplyLogs.getRoadBeginName());
                Integer byEndName = roadNodesMapper.selectIdByName(roadApplyLogs.getRoadEndName());

                if (byBeginName != null && byBeginName > 0) {// 3.1 起点存在，就找出id，并赋给路线申请信息
                    Integer nodeId = roadNodesMapper.selectIdByName(roadApplyLogs.getRoadBeginName());
                    System.out.println("找出来的起点id为:"+nodeId);
                    roadApplyLogs.setRoadBegin(nodeId);
                } else {
                    // 不存在就将该节点插入
                    RoadNodes roadNodes = new RoadNodes();
                    roadNodes.setNodeName(roadApplyLogs.getRoadBeginName());
                    roadNodes.setLongitude(nodeLngLat.getBeginLngLat()[0]); // 收费站结点经度
                    roadNodes.setLatitude(nodeLngLat.getBeginLngLat()[1]); // 收费站结点维度
                    roadNodesMapper.insert(roadNodes);
                    // 插入之后找出插入的结点id，赋给路线申请表
                    Integer idBegin = roadNodesMapper.selectIdByName(roadApplyLogs.getRoadBeginName());
                    roadApplyLogs.setRoadBegin(idBegin);
                }
                if (byEndName != null && byEndName > 0) {// 3.1 终点存在，就找出id，并赋给路线申请信息
                    Integer nodeId = roadNodesMapper.selectIdByName(roadApplyLogs.getRoadEndName());
                    roadApplyLogs.setRoadEnd(nodeId);
                } else {
                    // 不存在就将该节点插入
                    RoadNodes roadNodes = new RoadNodes();
                    roadNodes.setNodeName(roadApplyLogs.getRoadEndName());
                    roadNodes.setLongitude(nodeLngLat.getEndLngLat()[0]); // 收费站结点经度
                    roadNodes.setLatitude(nodeLngLat.getEndLngLat()[1]); // 收费站结点维度
                    roadNodesMapper.insert(roadNodes);

                    // 插入之后找出插入的结点id，赋给路线申请表
                    Integer idEnd = roadNodesMapper.selectIdByName(roadApplyLogs.getRoadEndName());
                    roadApplyLogs.setRoadEnd(idEnd);
                }
            }
            // 插入此路线申请
            int insertNumber = applyLogsDao.insert(roadApplyLogs);
            if (insertNumber > 0) {
                return DragonResult.ok();
            } else {
                return DragonResult.fail("提交失败");
            }
        }else{
            // 如果采用最新算法(WhetherUserAdvice == 2)，有几点考虑：
            // 1.存入哪个表呢？毕竟审核员审核的话，也要进行可视化显示
            // 依旧存入tbl_road_apply_logs表中，那就直接将之存入即可,只不过此时多了个paths数据罢了

            System.out.println("此时走向了智慧路线");
            // 插入此路线申请
            int insertNumber = applyLogsDao.insert(roadApplyLogs);
            if (insertNumber > 0) {
                return DragonResult.ok();
            } else {
                return DragonResult.fail("提交失败");
            }
        }
    }

    /**
     * 获得所有申请数量
     *
     * @return
     */
    @Override
    public int getApplyNum() {
        return applyLogsDao.selectApplyNum();
    }

    /**
     * 通过数量
     */
    @Override
    public int getPassApplyNum() {
        return applyLogsDao.selectPassApplyNum();
    }

    /**
     * 热门路线,设为前6个月
     *
     * @return
     */
    public List<RoadApplySum> getPopular() {
        String back = DateUtil.date2Str(Calendar.getInstance().getTime(), "yyyy-MM-dd");
        String front = DateUtil.getBeforeMonthTime(6);
        System.err.println(front+" "+back); // 打印
        return applyLogsDao.selectByPopular(front, back);
    }


}
